package gbench.mybatis.junit;

import org.junit.Test;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Random;
import java.util.function.Consumer;

import org.apache.ibatis.session.SqlSession;

import gbench.mybatis.MybatisUtil;
import gbench.mybatis.dao.UserDao;
import gbench.mybatis.entity.User;

/**
 * 
 * @author xuqinghua
 *
 */
public class JunitUser1 {

	/**
	 * 打印输出函数
	 * 
	 * @param objects
	 */
	public static void println(final Object... objects) {
		System.out.println(Arrays.asList(objects));
	}

	/*
	 * 添加用戶方法
	 */
	public void add1() {
		this.withTransaction(sqlSession -> {
			int i = sqlSession.insert("userns.add1");
			println("本次操作影响了" + i + "行数据");
		});

	}

	/**
	 * 添加用戶方法
	 * 
	 * @param user pojo
	 */
	public void add2(final User user) {
		this.withTransaction(sqlSession -> {
			int i = sqlSession.insert("userns.add2", user);
			println("本次操作影响了" + i + "行数据");
		});
	}

	/**
	 * 添加用戶方法
	 * 
	 * @param user
	 */
	public void selectAll() {
		this.withTransaction(sqlSession -> {
			final var c1 = sqlSession.selectList("userns.selectAll1").get(0).getClass();
			final var c2 = sqlSession.selectList("userns.selectAll2").get(0).getClass();
			println("selectAll1--->" + c1 + "\nselectAll2--->" + c2);
		});
	}

	/**
	 * 添加用戶方法
	 * 
	 * @param argUser
	 */
	public void selectById(final User argUser) {
		this.withTransaction(sqlSession -> {
			final var users = sqlSession.selectList("userns.selectById", argUser); // id 可以重复
			println("selectById ------------>" + users.get(0).getClass());
		});
	}

	/**
	 * 开启事务计算
	 * 
	 * @param action 回调函数 session->{}
	 */
	public void withTransaction(final Consumer<SqlSession> action) {
		SqlSession sqlSession = null;
		try {
			sqlSession = MybatisUtil.getSqlSession(); // 事务开始（默认）
			action.accept(sqlSession);
			sqlSession.commit(); // 事务提交
		} catch (Exception e) {
			e.printStackTrace();
			sqlSession.rollback(); // 事务回滚
			throw e;
		} finally {
			MybatisUtil.closeSqlSession(); // 关闭事务
		}
	}

	/**
	 * 使用DAO访问
	 */
	@Test
	public void bar() {
		this.withTransaction(sess -> {
			final var dao = sess.getMapper(UserDao.class);
			final var users = dao.selectAll1();
			users.forEach(e -> {
				println(e);
			});
		});
	}

	@Test
	public void foo() {
		this.add1();
		final var user = new User("1", "zhang" + LocalDateTime.now(), "" + new Random().nextInt(10),
				Math.random() > 0.5 ? "M" : "W");
		this.add2(user);
		this.selectAll();
		this.selectById(user);
	}

}
